//
//  AWRefreshControl.swift
//  WeiBo
//
//  Created by AaronWei on 2017/6/11.
//  Copyright © 2017年 AaronWei. All rights reserved.
//

import UIKit

enum AWRefreshControlType {
    
    case normal
    case pulling
    case refreshing
    
}

private let AWRefreshControlHeight: CGFloat = 50

class AWRefreshControl: UIControl {
    
    var refreshType: AWRefreshControlType = .normal {
        
        didSet {
            
            switch refreshType {
                
            case .normal:
                
                pullRefreshView.isHidden = false
                
                indicatorView.stopAnimating()
                
                refreshMessageLabel.text = "下拉刷新"
                
                UIView.animate(withDuration: 0.25, animations: {
                    
                    self.pullRefreshView.transform = CGAffineTransform.identity
                    
                }, completion: { (_) in
                    
                    if oldValue == .refreshing {
                        
                        UIView.animate(withDuration: 0.25, animations: { 
                            
                            self.currentScrollView?.contentInset.top -= AWRefreshControlHeight
                            
                        })
                        
                    }
                    
                })
                
            case .pulling:
             
                UIView.animate(withDuration: 0.25, animations: { 
                    
                    self.pullRefreshView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
                    
                })
                
                refreshMessageLabel.text = "松手刷新"
                
            case .refreshing:
                
                pullRefreshView.isHidden = true
                
                indicatorView.startAnimating()
                
                refreshMessageLabel.text = "正在刷新"
                
                UIView.animate(withDuration: 0.25, animations: { 
                    
                    self.currentScrollView?.contentInset.top += AWRefreshControlHeight
                    
                }, completion: { (_) in
                    
                    self.sendActions(for: .valueChanged)
                    
                })
              
            }
            
        }
        
    }
    
    var currentScrollView: UIScrollView?
    
    fileprivate lazy var pullRefreshView: UIImageView = UIImageView(image: #imageLiteral(resourceName: "tableview_pull_refresh"))
    
    fileprivate lazy var refreshMessageLabel: UILabel = UILabel(title: "下拉刷新", fontSize: 12, textColor: UIColor.gray, maxWidth: nil)
    
    fileprivate lazy var indicatorView: UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)

    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        
        backgroundColor = UIColor(white: 0.95, alpha: 1)
        
        addSubview(pullRefreshView)
        
        addSubview(refreshMessageLabel)
        
        addSubview(indicatorView)
        
        pullRefreshView.translatesAutoresizingMaskIntoConstraints = false
        refreshMessageLabel.translatesAutoresizingMaskIntoConstraints = false
        indicatorView.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: pullRefreshView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: pullRefreshView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: -35))
        
        addConstraint(NSLayoutConstraint(item: refreshMessageLabel, attribute: .centerY, relatedBy: .equal, toItem: pullRefreshView, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: refreshMessageLabel, attribute: .leading, relatedBy: .equal, toItem: pullRefreshView, attribute: .trailing, multiplier: 1, constant: 0))
        
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerY, relatedBy: .equal, toItem: pullRefreshView, attribute: .centerY, multiplier: 1, constant: 0))
        addConstraint(NSLayoutConstraint(item: indicatorView, attribute: .centerX, relatedBy: .equal, toItem: pullRefreshView, attribute: .centerX, multiplier: 1, constant: 0))
        
    }
    
    func endRefreshing() {
        
        refreshType = .normal
        
    }
    
    override func willMove(toSuperview newSuperview: UIView?) {
        
        if newSuperview is UIScrollView {
            
            let scrollView = newSuperview as! UIScrollView
            
            scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil)
            
            self.frame.size.width = scrollView.frame.size.width
            
            self.frame.size.height = AWRefreshControlHeight
            
            self.frame.origin.y = -AWRefreshControlHeight
            
            currentScrollView = scrollView
            
        }
        
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        
        let contentOffsetY = currentScrollView!.contentOffset.y
        
        if currentScrollView!.isDragging {
            
            let limitMaxY = -(currentScrollView!.contentInset.top + AWRefreshControlHeight)
            
            if contentOffsetY < limitMaxY && refreshType == .normal {
                
                refreshType = .pulling
                
            } else if contentOffsetY >= limitMaxY && refreshType == .pulling {
                
                refreshType = .normal
                
            }
            
        } else {
            
            if refreshType == .pulling {
                
                refreshType = .refreshing
                
            }
            
        }
        
    }
    
    deinit {
        currentScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }

}
